package com.team2.insulatingtools.modular.tools.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.roses.kernel.system.modular.organization.entity.HrOrganization;
import cn.stylefeng.roses.kernel.system.modular.organization.mapper.HrOrganizationMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.team2.insulatingtools.constants.ToolsStatus;
import com.team2.insulatingtools.modular.system.entity.ToolsHrOrganization;
import com.team2.insulatingtools.modular.system.service.OrgService;
import com.team2.insulatingtools.modular.tools.dto.SetKeeperDto;
import com.team2.insulatingtools.modular.tools.dto.QuotaDetailDto;
import com.team2.insulatingtools.modular.tools.dto.ToolKeeperLogDto;
import com.team2.insulatingtools.modular.tools.dto.ToolsDto;
import com.team2.insulatingtools.modular.tools.entity.Category;
import com.team2.insulatingtools.modular.tools.entity.Tools;
import com.team2.insulatingtools.modular.tools.enums.ToolsExceptionEnum;
import com.team2.insulatingtools.modular.tools.mapper.CategoryMapper;
import com.team2.insulatingtools.modular.tools.mapper.ToolsMapper;
import com.team2.insulatingtools.modular.tools.pojo.request.ReminderRequest;
import com.team2.insulatingtools.modular.tools.pojo.request.ScrapRequest;
import com.team2.insulatingtools.modular.tools.pojo.request.ToolsRequest;
import com.team2.insulatingtools.modular.tools.pojo.response.ToolReminderResponse;
import com.team2.insulatingtools.modular.tools.service.ScrapService;
import com.team2.insulatingtools.modular.tools.service.ToolsService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 绝缘工具 业务实现层
 *
 * @author vcz
 * @date 2023/04/04 16:58
 */
@Service
public class ToolsServiceImpl extends ServiceImpl<ToolsMapper, Tools> implements ToolsService {

    @Resource
    private ToolsMapper toolsMapper;
    @Resource
    private HrOrganizationMapper hrOrganizationMapper;
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private OrgService orgService;
    @Resource
    private ScrapService scrapService;

    public static int REMIND_DAYS = 20;

    public static String CURRENT_DAY ;



    @Override
    public ResponseData<?> add(ToolsRequest toolsRequest) {
        Tools tools = new Tools();
        BeanUtil.copyProperties(toolsRequest, tools);
        ToolsDto toolsDto1 = new ToolsDto();
        ToolsDto toolsDto2 = new ToolsDto();
        ToolsDto toolsDto3 = new ToolsDto();
        toolsDto1 = toolsMapper.selectAllByCount(tools.getQuotaId(), tools.getName());
        toolsDto2 = toolsMapper.selectExists(tools.getQuotaId(), tools.getName());
        toolsDto3 = toolsMapper.selectIfNew(tools.getQuotaId(), tools.getName());
        if (toolsDto2.getResult() == 1) {
            return new ErrorResponseData<ToolsDto>("2", "该工具不在定额单上，禁止添加");
        } else if (toolsDto2.getResult() == 0) {
            if (toolsDto3.getResult() == 0) {
                if (toolsDto1.getResult() == 1) {
                    return new ErrorResponseData<ToolsDto>("1", "定额已满");
                } else if (toolsDto1.getResult() == 0) {
                    this.save(tools);
                    return new SuccessResponseData<>();
                }
            } else if (toolsDto3.getResult() == 1) {
                this.save(tools);
                return new SuccessResponseData<>();
            }
        }


        return new ErrorResponseData<Tools>("000", "无效错误");
    }

    @Override
    public ResponseData<?> del(ToolsRequest toolsRequest) {
        Tools tools = this.queryTools(toolsRequest);
        ToolsDto toolsDto1 = new ToolsDto();
        toolsDto1 = toolsMapper.selectDelete(tools.getId());
        if (toolsDto1.getResult() == 0) {
            return new ErrorResponseData<ToolsDto>("1", "状态正常不能删除");
        } else {
            this.removeById(tools.getId());
            return new SuccessResponseData<>();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(ToolsRequest toolsRequest) {
        Tools tools = this.queryTools(toolsRequest);
        BeanUtil.copyProperties(toolsRequest, tools);
        LambdaUpdateWrapper<Tools> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Tools::getId,tools.getId());
        if("报废".equals(tools.getOperateConclusion())){
            tools.setStatus(ToolsStatus.报废未补充.getValue());
            //报废情况处理
            updateWrapper.set(Tools::getTestDate,null);
            updateWrapper.set(Tools::getTester,null);
            updateWrapper.set(Tools::getAuditor,null);
            updateWrapper.set(Tools::getOperateDate,null);
            updateWrapper.set(Tools::getOperateConclusion,null);
            ScrapRequest  scrapRequest = new ScrapRequest(tools.getId());
            scrapService.add(scrapRequest);
        }else{
            updateWrapper.set(Tools::getStatus,ToolsStatus.正常.getValue());
            if (tools.getTestDate()!=null){
                //有效日期根据基础信息管理中试验周期（月）来确定
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(tools.getTestDate());
                calendar.add(Calendar.MONTH,tools.getCycle().intValue());
                tools.setExpireDate(calendar.getTime());
            }
        }
        this.update(tools,updateWrapper);
    }

    @Override
    public Tools detail(ToolsRequest toolsRequest) {
        return this.queryTools(toolsRequest);
    }

    @Override
    public PageResult<Tools> findPage(ToolsRequest toolsRequest) {
        LambdaQueryWrapper<Tools> wrapper = createWrapper(toolsRequest);
        Page<Tools> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    @Override
    public ResponseData changeKeeper(ToolsRequest toolsRequest) {
        Tools tools = new Tools();
        BeanUtils.copyProperties(toolsRequest, tools);
        if (this.updateById(tools)) {
            int tid = tools.getId();
            String specification = toolsMapper.selectOne(new QueryWrapper<Tools>().eq("id", toolsRequest.getId())).getSpecification();
            String keeper = tools.getKeeper();
            Integer status = toolsMapper.selectOne(new QueryWrapper<Tools>().eq("id", toolsRequest.getId())).getStatus();
            this.addToolLog(tid,specification,keeper,status);
            return new SuccessResponseData();
        } else {
            return new ErrorResponseData("10000", "修改保管人失败");
        }
    }

//    @Override
//    public ResponseData selByWorkshop(String speciality, String workshopName, String groupName) {
//        Long id = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", workshopName).eq("speciality", speciality)).getOrgId();
//        Long groupId = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", groupName)).getOrgId();
//        if (groupName == null) {
//            return new SuccessResponseData(toolsMapper.selByWorkshop(id + ""));
//        } else {
//            return new SuccessResponseData(toolsMapper.selByGroup(groupId + ""));
//        }
//
//    }

    @Override
    public ResponseData selByOrgName(String speciality, String orgName) {
        Long orgId = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", orgName).eq("speciality", speciality)).getOrgId();
        Integer orgType = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", orgName).eq("speciality", speciality)).getOrgType();
        if (orgType == 3) {
            return new SuccessResponseData(toolsMapper.selByWorkshop(orgId + ""));
        }
        if (orgType == 4) {
            return new SuccessResponseData(toolsMapper.selByGroup(orgId + ""));
        } else {
            return new ErrorResponseData("10000", "查询失败");
        }
    }


//    @Override
//    public ResponseData SelByWorkshopAndTools(String speciality, String workshopName, String groupName, String categoryName) {
//        Long id = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", workshopName).eq("speciality", speciality)).getOrgId();
//        Integer cid = categoryMapper.selectOne(new QueryWrapper<Category>().eq("name", categoryName)).getId();
//        Long groupId = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", groupName)).getOrgId();
//        if (groupName == null) {
//            return new SuccessResponseData(toolsMapper.selByWorkshopAndTools(id + "", cid));
//        } else {
//            return new SuccessResponseData(toolsMapper.selByGroupAndTools(groupId + "", cid));
//        }
//    }

    @Override
    public ResponseData SelByOrgNameAndTools(String speciality, String orgName, String categoryName) {
        Long orgId = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", orgName).eq("speciality", speciality)).getOrgId();
        Integer orgType = hrOrganizationMapper.selectOne(new QueryWrapper<HrOrganization>().eq("org_name", orgName).eq("speciality", speciality)).getOrgType();
        Integer cid = categoryMapper.selectOne(new QueryWrapper<Category>().eq("name", categoryName)).getId();
        if (orgType == 3) {
            return new SuccessResponseData(toolsMapper.selByWorkshopAndTools(orgId + "", cid));
        }
        if (orgType == 4) {
            return new SuccessResponseData(toolsMapper.selByGroupAndTools(orgId + "", cid));
        } else {
            return new ErrorResponseData("10000", "查询失败");
        }
    }

//    @Override
//    public ResponseData changeKeeperBatch(int id, String keeper) {
//        if (toolsMapper.changeKeeperBatch(id, keeper) > 0) {
//            return new SuccessResponseData();
//        } else {
//            return new ErrorResponseData("10000", "新增保管人失败");
//        }
//    }

    @Override
    public ResponseData changeKeeperBatch(SetKeeperDto dto) {
        dto.getList().forEach(toolMsgDto -> {
            UpdateWrapper<Tools> equal = new UpdateWrapper<Tools>().eq("id", toolMsgDto.getId()).set("keeper", dto.getKeeper());
            toolsMapper.update(null, equal);
            int tid = toolMsgDto.getId();
//            String keeper = toolsMapper.selectOne(new QueryWrapper<Tools>().eq("id", tid)).getKeeper();
            String keeper = dto.getKeeper();
            String specification = toolsMapper.selectOne(new QueryWrapper<Tools>().eq("id", tid)).getSpecification();
            Integer status = toolsMapper.selectOne(new QueryWrapper<Tools>().eq("id", tid)).getStatus();
            this.addToolLog(tid,specification,keeper,status);
        });
        return new SuccessResponseData();
    }

    @Override
    public ResponseData showKeeperLog(int tid) {
        return new SuccessResponseData(toolsMapper.selKeeperLog(tid));
    }


    @Override
    public List<ToolReminderResponse> getToolAboutToExpire(ReminderRequest reminderRequest) {
        if (reminderRequest.getDays() != null) {
            REMIND_DAYS = reminderRequest.getDays();
        }
        LocalDate date = LocalDate.now().plusDays(REMIND_DAYS);
        List<Long> list ;
        List<ToolsHrOrganization> orgList;
        if (reminderRequest.getOrgId() != null ){
            orgList = orgService.getSubOrg(reminderRequest.getOrgId());
        }else{
            orgList = orgService.getOrgsByRole(reminderRequest.getSpeciality().toString());
        }
        list = orgList.stream().map(ToolsHrOrganization::getOrgId).collect(Collectors.toList());
        this.expire();
        return toolsMapper.getToolExpire(date,list);
    }

    /**
     * 自动报废情况处理
     */
    @Transactional(rollbackFor = Exception.class)
    public void expire(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String curr = sdf.format(Calendar.getInstance().getTime());
        if (CURRENT_DAY == null || !curr.equals(CURRENT_DAY)){
            CURRENT_DAY = curr;
            toolsMapper.updateBatchByExpireDate(curr);
            LambdaQueryWrapper<Tools> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.le(ObjectUtil.isNotNull(curr), Tools::getExpireDate, curr);
            List<Tools> list = this.list(queryWrapper);
            for (Tools tool :list) {
                LambdaUpdateWrapper<Tools> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(Tools::getTestDate,null);
                updateWrapper.set(Tools::getTester,null);
                updateWrapper.set(Tools::getAuditor,null);
                updateWrapper.set(Tools::getOperateDate,null);
                updateWrapper.set(Tools::getOperateConclusion,null);
                this.update(tool,updateWrapper);
                scrapService.add(new ScrapRequest(tool.getId()));
            }
        }
    }

    @Override
    public List<Tools> findList(ToolsRequest toolsRequest) {
        LambdaQueryWrapper<Tools> wrapper = this.createWrapper(toolsRequest);
        return this.list(wrapper);
    }

    /**
     * 获取信息
     *
     * @author vcz
     * @date 2023/04/04 16:58
     */
    private Tools queryTools(ToolsRequest toolsRequest) {
        Tools tools = this.getById(toolsRequest.getId());
        if (ObjectUtil.isEmpty(tools)) {
            throw new ServiceException(ToolsExceptionEnum.TOOLS_NOT_EXISTED);
        }
        return tools;
    }

    /**
     * 创建查询wrapper
     *
     * @author vcz
     * @date 2023/04/04 16:58
     */
    private LambdaQueryWrapper<Tools> createWrapper(ToolsRequest toolsRequest) {
        LambdaQueryWrapper<Tools> queryWrapper = new LambdaQueryWrapper<>();

        Integer id = toolsRequest.getId();
        Integer speciality = toolsRequest.getSpeciality();
        Integer quotaId = toolsRequest.getQuotaId();
        String name = toolsRequest.getName();
        Integer status = toolsRequest.getStatus();
        String specification = toolsRequest.getSpecification();
        String testDate = toolsRequest.getTestDate();
        String expireDate = toolsRequest.getExpireDate();
        String tester = toolsRequest.getTester();
        String auditor = toolsRequest.getAuditor();
        String operateConclusion = toolsRequest.getOperateConclusion();
        String operateDate = toolsRequest.getOperateDate();
        String keeper = toolsRequest.getKeeper();
        Float workingVoltage = toolsRequest.getWorkingVoltage();
        Float acTestVoltage = toolsRequest.getAcTestVoltage();
        Float length = toolsRequest.getLength();
        Float lastingTime = toolsRequest.getLastingTime();
        Float cycle = toolsRequest.getCycle();
        Integer leakageCurrentNew = toolsRequest.getLeakageCurrentNew();
        Integer leakageCurrentRunning = toolsRequest.getLeakageCurrentRunning();
        Integer isMultisection = toolsRequest.getIsMultisection();
        String unit = toolsRequest.getUnit();
        String purpose = toolsRequest.getPurpose();
        String remark = toolsRequest.getRemark();

        queryWrapper.eq(ObjectUtil.isNotNull(id), Tools::getId, id);
        queryWrapper.eq(ObjectUtil.isNotNull(quotaId), Tools::getQuotaId, quotaId);
        queryWrapper.like(ObjectUtil.isNotEmpty(name), Tools::getName, name);
        queryWrapper.eq(ObjectUtil.isNotNull(status), Tools::getStatus, status);
        queryWrapper.like(ObjectUtil.isNotEmpty(specification), Tools::getSpecification, specification);
        queryWrapper.eq(ObjectUtil.isNotNull(testDate), Tools::getTestDate, testDate);
        queryWrapper.eq(ObjectUtil.isNotNull(expireDate), Tools::getExpireDate, expireDate);
        queryWrapper.like(ObjectUtil.isNotEmpty(tester), Tools::getTester, tester);
        queryWrapper.like(ObjectUtil.isNotEmpty(auditor), Tools::getAuditor, auditor);
        queryWrapper.like(ObjectUtil.isNotEmpty(operateConclusion), Tools::getOperateConclusion, operateConclusion);
        queryWrapper.eq(ObjectUtil.isNotNull(operateDate), Tools::getOperateDate, operateDate);
        queryWrapper.like(ObjectUtil.isNotEmpty(keeper), Tools::getKeeper, keeper);
        queryWrapper.eq(ObjectUtil.isNotNull(workingVoltage), Tools::getWorkingVoltage, workingVoltage);
        queryWrapper.eq(ObjectUtil.isNotNull(acTestVoltage), Tools::getAcTestVoltage, acTestVoltage);
        queryWrapper.eq(ObjectUtil.isNotNull(length), Tools::getLength, length);
        queryWrapper.eq(ObjectUtil.isNotNull(lastingTime), Tools::getLastingTime, lastingTime);
        queryWrapper.eq(ObjectUtil.isNotNull(cycle), Tools::getCycle, cycle);
        queryWrapper.eq(ObjectUtil.isNotNull(leakageCurrentNew), Tools::getLeakageCurrentNew, leakageCurrentNew);
        queryWrapper.eq(ObjectUtil.isNotNull(leakageCurrentRunning), Tools::getLeakageCurrentRunning, leakageCurrentRunning);
        queryWrapper.eq(ObjectUtil.isNotNull(isMultisection), Tools::getIsMultisection, isMultisection);
        queryWrapper.like(ObjectUtil.isNotEmpty(unit), Tools::getUnit, unit);
        queryWrapper.like(ObjectUtil.isNotEmpty(purpose), Tools::getPurpose, purpose);
        queryWrapper.like(ObjectUtil.isNotEmpty(remark), Tools::getRemark, remark);
        queryWrapper.eq(ObjectUtil.isNotNull(speciality), Tools::getSpeciality, speciality);

        return queryWrapper;
    }

    @Override
    public ResponseData<?> addBatch(ToolsRequest toolsRequest, int quotaCount) {
        QuotaDetailDto quotaDetailDto = toolsMapper.selectCurrentCountByOrgQuota(toolsRequest.getQuotaId(), toolsRequest.getName());
        int number = quotaDetailDto == null ? 0 : quotaDetailDto.getMaxNumber();
        int currentCount = quotaDetailDto == null ? 0 : quotaDetailDto.getCount();
        List<Tools> list = new ArrayList<>();
        for (int i = 0; i < quotaCount - currentCount; i++) {
            Tools tools = new Tools();
            BeanUtil.copyProperties(toolsRequest, tools);
            number++;
            tools.setNumber(number);
            tools.setName(toolsRequest.getName());
            list.add(tools);
        }
        this.saveBatch(list);
        return new SuccessResponseData<>();
    }

    @Override
    public void addToolLog(int toolId, String specification, String keeper, int status){
        ToolKeeperLogDto toolKeeperLogDto = new ToolKeeperLogDto(toolId, specification, keeper, status);
        toolsMapper.insertKeeperLog(toolKeeperLogDto);
    }

    @Override
    public void deleteBatchByToolIdList(List<Integer> idList) {
        toolsMapper.deleteBatchIds(idList);
    }

}
